package category

import (
	"github.com/jinzhu/gorm"
	"go-gin-api/app/model"
	grpccategory "go-gin-api/app/proto/category"
	"go-gin-api/app/util/constutil"
	"time"
)

type Category struct {
	ID        int       `gorm:"column:id;primary_key" form:"id" json:"id"`
	Name      string    `form:"name" json:"name"`
	Pid       int       `form:"pid" json:"pid"`
	SortOrder int       `form:"sort_order" json:"sort_order"`
	Status    int       `form:"status" json:"status"`
	CreatedAt time.Time `form:"created_at" json:"created_at"`
	UpdatedAt time.Time `form:"updated_at" json:"updated_at"`
}

func (Category) TableName() string {
	return constutil.TablePrefix + "category"
}



type CategoryRepository interface {
	CategoryAdd(req *grpccategory.CategoryRequest) (err error)
	CategoryDel(req *grpccategory.CategoryDelRequest) (err error)
	CategoryUpdate(req *grpccategory.CategoryUpdateRequest) (err error)
	CategoryList(req *grpccategory.CategoryListRequest) (res []Category, err error)
	CategoryInfo(req *grpccategory.CategoryInfoRequest) (value Category, err error)
	CategoryByName(name string) (value Category)
	ExistsCategoryByName(name string,id int) (res bool)
}

type MysqlCategory struct {

}

func NewMysqlCategory() CategoryRepository {
	return &MysqlCategory{

	}
}


func (m *MysqlCategory) CategoryAdd(req *grpccategory.CategoryRequest) (err error) {
	defer model.Db.Close()
	model.Db = model.Connect()
	value := Category{
		ID:        0,
		Pid:       0,
		SortOrder: 0,
		Name:      req.Name,
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}
	err = model.Db.Hander.Model(Category{}).Create(&value).Error
	return
}

func (m *MysqlCategory) CategoryByName(name string) (value Category) {
	defer model.Db.Close()
	model.Db = model.Connect()
	model.Db.Hander.Model(Category{}).Where("name= ?",name).First(&value)
	return
}

func (m *MysqlCategory) ExistsCategoryByName(name string,id int) (res bool) {
	defer model.Db.Close()
	model.Db = model.Connect()
	var count int
	categoryModel := model.Db.Hander.Model(Category{}).Where("name= ?",name)
	if id > 0 {
		categoryModel = categoryModel.Where("id = ?",id)
	}
	categoryModel.Count(&count)
	if count > 0 {
		res = true
	}
	return
}

func (m *MysqlCategory) CategoryDel(req *grpccategory.CategoryDelRequest) (err error) {
	defer model.Db.Close()
	model.Db = model.Connect()
	var value Category
	model.Db.Hander.Model(Category{}).Where("id = ?", req.Id).First(&value)
	err = gorm.ErrRecordNotFound
	if value.ID > 0 {
		err = model.Db.Hander.Where("id = ?", req.Id).Delete(&value).Error
	}
	return
}

func (m *MysqlCategory) CategoryUpdate(req *grpccategory.CategoryUpdateRequest) (err error) {
	defer model.Db.Close()
	model.Db = model.Connect()
	var value Category
	model.Db.Hander.Model(Category{}).Where("id = ?", req.Id).First(&value)
	err = gorm.ErrRecordNotFound
	if value.ID > 0 {
		value.Name = req.Name
		err = model.Db.Hander.Where("id = ?", req.Id).Update(&value).Error
	}
	return
}

func (m *MysqlCategory) CategoryList(req *grpccategory.CategoryListRequest) (res []Category, err error) {
	defer model.Db.Close()
	model.Db = model.Connect()
	err = model.Db.Hander.Model(Category{}).
		Scopes(withStatus(req.Status), withLikeCategoryName(req.Name), withCreatedAt(req.CreatedAt)).
		Offset((req.Page-1) * req.Limit).
		Limit(req.Limit).
		Find(&res).Error
	return
}

func (m *MysqlCategory) CategoryInfo(req *grpccategory.CategoryInfoRequest) (value Category, err error) {
	defer model.Db.Close()
	model.Db = model.Connect()
	err = model.Db.Hander.Model(Category{}).Scopes(withCategoryID(req.Id)).First(&value).Error
	return
}

func withStatus(status int32) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		where := 1
		if status == 0 {
			where = 0
		}
		return db.Where("status = ?", where)
	}
}

func withLikeCategoryName(name string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if name != "" {
			return db.Where("name like %?%", name)
		}
		return db
	}
}

func withCreatedAt(createdAt string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if createdAt != "" {
			return db.Where("createdAt > ?", createdAt)
		}
		return db
	}
}

func withCategoryID(id int32) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if id > 0 {
			return db.Where("id = ? ", id)
		}
		return db
	}
}
